import {ExtendOption} from "./extend";

/**
 * 事件方法
 */
export type YvanEventFunction<T> = (sender: T, ...args: any) => any

/**
 * 事件类型
 */
export type YvanEvent<T> = string | YvanEventFunction<T>

/**
 * 产生一个结果的方法
 */
export type ProductFunction<T> = () => T

/**
 * 可能 T | Promise<T>
 */
export type PromiseMabe<T> = Promise<T> | T

/**
 * 处理 VJson 的
 * @param this 是指 scope 对象
 * @param vjson 是待处理的 VJson 对象
 * @result 返回处理 VJson 的 Promise 异步结果
 */
export type VJsonProcess = (this: any, vjson: VJson) => Promise<VJson>

/**
 * $watch:{} 定义
 */
export interface WatchProperty<T> {
    $watch: () => PromiseMabe<T>,
}

/**
 * $watch:{}, $then:{} 定义
 */
export interface WatchThenProperty<T> {
    $watch: () => PromiseMabe<any>,
    $then: (watchResult: any) => PromiseMabe<T>
}

/**
 * 可被观测属性定义, 例如:
 * visible:
 *      boolean |
 *      ()=>PromiseMabe<string> |
 *      { $watch:()=>PromiseMabe<boolean> } |
 *      { $watch:()=>PromiseMabe<boolean>, $then:()=>PromiseMabe<boolean> }
 */
export type ComplexPropertyValue<T> =
    T
    | ProductFunction<PromiseMabe<T>>
    | WatchProperty<T>
    | WatchThenProperty<T>

export const NotModify = Symbol('NotModify')
export const ClearData = Symbol('ClearData')

export type DataResult<T> = PromiseMabe<T> | typeof NotModify | typeof ClearData

export interface ValueStartWatchOption {
    /**
     * 取数目标 $watch 的目标，也是所有回调方法的 this 对象
     */
    scope: any

    /**
     * 被 watch 的属性名（ then 回写的目标属性 ）
     */
    propertyName: string
}

/**
 * "值定义" 的声明，用于定义 scope 中计算值的定义结果
 */
export abstract class ValueDefine<T> {

    readonly isValueDefine: boolean = true

    /**
     * 第一次运行时，获取的值
     */
    relationInstance: any

    /**
     * 开启监听
     * @param executeOption
     */
    abstract start(executeOption: ValueStartWatchOption): void

    /**
     * 结束监听
     */
    abstract dispose(): void

    /**
     * 只获取执行结果，不监听，不用 dispose
     */
    abstract get(): DataResult<T>
}

export interface PlainObject {
    [propsName: string]: any;
}

export interface VJson {
    [propName: string]: any;
}

export interface ScopeOption {
}

// VJson 组件的 Props 基础属性
export interface VJsonComponentProp<CtlProp> {

    /**
     * 被传递的默认值
     */
    $default: any

    /**
     * scope 上下文
     */
    $context: {
        /**
         * 用户 scope 组件
         */
        scopeInstance: any

        /**
         * 模块全局 vjson 描述
         */
        rootVJson: VJson

        /**
         * 全局上下文
         */
        appContext: ExtendOption
    }

    /**
     * 向下传递的 vjson
     */
    vjson: CtlProp & { [key: string]: any }

    /**
     * 其他属性
     */
    [key: string]: any
}